package jp.gr.java_conf.ryz.summarize.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import jp.gr.java_conf.ryz.summarize.client.SummarizeService;
import jp.gr.java_conf.ryz.summarize.shared.model.Board;
import jp.gr.java_conf.ryz.summarize.shared.model.Category;
import jp.gr.java_conf.ryz.summarize.shared.model.Post;
import jp.gr.java_conf.ryz.summarize.shared.model.ThreadDetail;
import jp.gr.java_conf.ryz.summarize.shared.model.Thred;


import com.google.gwt.user.server.rpc.RemoteServiceServlet;

public class SummarizeServiceImpl extends RemoteServiceServlet implements SummarizeService
{
	/**
	 * serial version UID.
	 */
	private static final long serialVersionUID = 1112035006739880624L;
	
	/**
	 * logger.
	 */
	private static final Logger _logger = Logger.getLogger(SummarizeServiceImpl.class.getName());
	
	
	@Override
	public List<Category> getCategories() throws IllegalArgumentException
	{
		if (_logger.isLoggable(Level.INFO))
		{
			_logger.info("called getCategories.");
		}
		
		return getCategoriesInternal();
	}
	
	@Override
	public List<Thred> getThreads(String boardUrl) throws IllegalArgumentException
	{
		if (_logger.isLoggable(Level.INFO))
		{
			_logger.info("called getThreads. boardUrl=[" + boardUrl + "]");
		}
		
		return getThreadInternal(boardUrl);
	}
	
	public ThreadDetail getThreadDetail(String datUrl) throws IllegalArgumentException
	{
		if (_logger.isLoggable(Level.INFO))
		{
			_logger.info("called getThreadDetails.");
		}
		
		return getThreadDetailsInternal(datUrl);
	}
	
	
	private List<Category> getCategoriesInternal()
	{
		List<Category> categories = new ArrayList<Category>();
		
		try
		{
			URL url = new URL("http://menu.2ch.net/bbsmenu.html");
			HttpURLConnection connection = (HttpURLConnection)url.openConnection();
			connection.setRequestMethod("GET");
			connection.connect();
			
			_logger.info("ResponseCode=[" + connection.getResponseCode() + "]");
			
			if (connection.getResponseCode() == 200)
			{
				BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "Shift-JIS"));
				Category currentCategory = null;
				while (true)
				{
					String line = reader.readLine();
					if (line == null)
						break;
					
					if (isCategoryLine(line))
					{
						currentCategory = createCategory(line);
						categories.add(currentCategory);
					}
					
					if (isBoardLine(line))
					{
						if (currentCategory != null)
						{
							currentCategory.addBoard(createBoard(line));
						}
					}
				}
				
				StringBuilder sb = new StringBuilder();
				for (Category category : categories)
				{
					sb.append(category.toString());
				}
				
				_logger.info(sb.toString());
			}
		}
		catch (IOException e)
		{
			_logger.warning(e.toString());
		}
		
		
		return categories;
	}
	
	private boolean isCategoryLine(String line)
	{
		// MEMO : Sample
		//      : <BR><BR><B>hoge</B><BR>
		String regexp = "^<BR><BR><B>.*</B><BR>.*";
		return line.matches(regexp);
	}
	
	private Category createCategory(String line)
	{
		Category category = new Category();
		category.setName(getCategoryName(line));
		
		return category;
	}
	
	private String getCategoryName(String line)
	{
		return line.substring("<BR><BR><B>".length(), line.indexOf("</B><BR>"));
	}
	
	private boolean isBoardLine(String line)
	{
		// MEMO : Sample
		//      : <A HREF=http://headline.2ch.net/bbynews/>����headline</A><br>
		//      : <A HREF=http://www.monazilla.org/ TARGET=_blank>2ch�c�[��</A><br>
		String regexp = "^<A HREF=.*</A><br>";
		return line.matches(regexp);
	}
	
	private Board createBoard(String line)
	{
		Board board = new Board();
		board.setName(getBoardName(line));
		board.setUrl(getBoardUrl(line));
		
		return board;
	}
	
	private String getBoardName(String line)
	{
		line = line.substring(line.indexOf(">") + 1, line.length());
		return line.substring(0, line.indexOf("</A><br>"));
	}
	
	private String getBoardUrl(String line)
	{
		line = line.replaceFirst("<A HREF=", "");
		int index = line.indexOf(" TARGET=_blank");
		return index < 0
				? line.substring(0, line.indexOf(">"))
				: line.substring(0, index);
	}
	
	private List<Thred> getThreadInternal(String boardUrl)
	{
		List<Thred> result = new ArrayList<Thred>();
		
		try
		{
			URL url = new URL(boardUrl + "subject.txt");
			HttpURLConnection conn = (HttpURLConnection)url.openConnection();
			
			int responseCode = conn.getResponseCode();
			
			_logger.info("ResponseCode=[" + responseCode + "]");
			
			if (responseCode == 200)
			{
				BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "Shift-JIS"));
				while (true)
				{
					String line = reader.readLine();
					if (line == null)
						break;
					
					Thred thred = createThred(boardUrl, line);
					result.add(thred);
				}
			}
		}
		catch (IOException e)
		{
			_logger.warning(e.toString());
		}
		
		return result;
	}
	
	private Thred createThred(String boardUrl, String line)
	{
		Thred result = new Thred();
		
		String[] lines = line.split("<>", -1);
		result.setDatUrl(boardUrl + "/dat/" + lines[0]);
		result.setName(lines[1]);
		
		return result;
	}
	
	private ThreadDetail getThreadDetailsInternal(String datUrl)
	{
		ThreadDetail result = new ThreadDetail();
		
		try
		{
			URL url = new URL(datUrl);
			HttpURLConnection conn = (HttpURLConnection)url.openConnection();
			
			int responseCode = conn.getResponseCode();
			
			_logger.info("ResponseCode=[" + responseCode + "]");
			
			if (responseCode == 200)
			{
				BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "Shift-JIS"));
				int number = 1;
				while (true)
				{
					String line = reader.readLine();
					if (line == null)
						break;
					
					result.addPost(createPost(number++, line));
				}
			}
		}
		catch (IOException e)
		{
			_logger.warning(e.toString());
		}
		
		return result;
	}
	
	private Post createPost(int number, String line)
	{
		Post result = new Post();
		
		result.setNumber(number);
		result.setName(getPostName(line));
		result.setDate(getPostDate(line));
		result.setMail(getPostMail(line));
		result.setBody(getPostBody(line));
		
		return result;
	}
	
	private String getPostName(String line)
	{
		String[] sa = line.split("<>", -1);
		return sa[0];
	}
	
	private String getPostMail(String line)
	{
		String[] sa = line.split("<>", -1);
		return sa[1];
	}
	
	private String getPostDate(String line)
	{
		String[] sa = line.split("<>", -1);
		return sa[2];
	}
	
	private String getPostBody(String line)
	{
		String[] sa = line.split("<>", -1);
		String body = sa[3];
		
		// remove anchor tag.
		if (body.indexOf("<a") > -1)
		{
			body = body.replaceFirst("<a href.*target=\"_blank\">", "");
			body = body.replaceFirst("</a>", "");
		}
		return body;
	}
}
